package com.naiterui.ehp.ps.sms.controller.inner;

import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.ps.sms.cache.SmsRamCache;
import com.naiterui.ehp.ps.sms.exception.ExceptionCodes;
import com.naiterui.ehp.ps.sms.exception.SmsBusinessException;
import com.naiterui.ehp.ps.sms.factory.SendMessageUtil;
import com.naiterui.ehp.ps.sms.service.ISignatureService;
import com.naiterui.ehp.ps.sms.service.ITemplateService;
import com.naiterui.ehp.ps.sms.utils.RedisUtils;
import com.naiterui.ehp.ps.sms.utils.constants.RedisConstants;
import com.naiterui.ehp.ps.sms.utils.constants.SmsConstants;
import com.naiterui.ehp.ps.sms.vo.MessageResponseVO;
import com.naiterui.ehp.ps.sms.vo.SendInfoParamVO;
import com.naiterui.ehp.ps.sms.vo.SignatureVO;
import com.naiterui.ehp.ps.sms.vo.TemplateVO;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Set;

/**
 * 短信发送API controller
 *
 * @author
 * @since 1.0.0
 */
@RequestMapping("sms/inner/api/message")
@Controller
@Slf4j
@Api(tags = SwaggerTag.SMS + SwaggerTag.INNER_API + SwaggerTag.MESSAGE_SEND)
public class InnerApiController {

    @Autowired
    private ITemplateService templateService;

    @Autowired
    private ISignatureService signatureService;

    @RequestMapping("singlesend")
    @ResponseBody
    public ResponseVO<MessageResponseVO> singleSend(SendInfoParamVO sendInfoParamVO) {
        if (sendInfoParamVO == null) {
            log.error("发送短信失败，参数为空");
            return PublicService.returnResponseVO(ExceptionCodes.PARAM_ERROR, null);
        }
        Integer templateId = sendInfoParamVO.getTemplateId();
        String phone = sendInfoParamVO.getPhone();
        String[] datas = sendInfoParamVO.getDatas();
        // 校验当前短信通道
        Integer platformId = SmsRamCache.getCurrentPlatformId();
        if (platformId == null) {
            log.error("发送短信失败，当前平台未设置。platformId: {}, sendInfoParamVO: {}", platformId, sendInfoParamVO);
            return PublicService.returnResponseVO(ExceptionCodes.SMS_PLATFOMR_NOT_SET, null);
        }

        TemplateVO templateVO = templateService.getTemplateFromCache(platformId, templateId);
        if (templateVO == null || templateVO.getId() == null || templateVO.getStatus() != SmsConstants.EFFECTIVE_STAUTS) {
            log.error("发送短信失败，模版未设置。 sendInfoParamVO: {}, templateVO: {}", sendInfoParamVO, templateVO);
            return PublicService.returnResponseVO(ExceptionCodes.SMS_TEMPLATE_NOT_SET, null);
        }

        // 校验模版配置的签名
        SignatureVO signatureVO = signatureService.getSendSignatureFromCache(templateVO.getSignatureId());
        if (signatureVO == null) {
            log.error("发送短信失败，模版未设置。 sendInfoParamVO: {}, signatureId: {}", sendInfoParamVO, templateVO.getSignatureId());
            return PublicService.returnResponseVO(ExceptionCodes.SMS_SIGNATURE_NOT_SET, null);
        }

        // 校验短信屏蔽名单
        if (containsShieldPhone(phone)) {
            try {
                String content = SendMessageUtil.replaceTemplateContent(templateVO.getContent(), datas);
                log.info("屏蔽发送短信 phone:{}, platformId:{}, content:{}", phone, platformId, content);
                return PublicService.returnResponseVO(ExceptionCodes.SUCCESS, null);
            } catch (SmsBusinessException e) {
                log.error("发送短信失败,平台ID: {}, 短信模板ID: {}, 签名：{}, 模板内容: {}, 发送手机号： {}, 模板参数： {}", platformId, templateId, signatureVO,
                        templateVO.getContent(), phone, datas, e);
                return PublicService.returnResponseVO(e.getCode(), null);
            }
        }

        // 发送短信
        try {
            MessageResponseVO messageResponseVO =
                SendMessageUtil.singleSend(platformId, signatureVO, templateVO, phone, datas);
            if (messageResponseVO == null || !messageResponseVO.getStatusCode().equals(String.valueOf(ExceptionCodes.SUCCESS))) {
                return PublicService.returnResponseVO(ExceptionCodes.SMS_PLATFORM_RETURN_ERROR, messageResponseVO);
            }
        } catch (SmsBusinessException e) {
            log.error("发送短信失败,平台ID: {}, 短信模板ID: {}, 签名：{}, 模板内容: {}, 发送手机号： {}, 模板参数： {}", platformId, templateId, signatureVO,
                    templateVO.getContent(), phone, datas, e);
            return PublicService.returnResponseVO(e.getCode(), null);
        }
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS, null);
    }

    /**
     * 更新短信模板
     *
     * @return
     */
    @RequestMapping("template/update")
    @ResponseBody
    public ResponseVO<Void> updateTemplate(TemplateVO templateVO) throws BusinessException {
        log.info("");
        templateService.updateTemplate(templateVO);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }




    /**
     * 屏蔽短信-查询列表(内部手动使用)
     *
     * @return
     */
    @RequestMapping("shield/list")
    @ResponseBody
    public ResponseVO<Set<String>> getShieldPhone() {
        Set<String> phoneSet = RedisUtils.smember(RedisConstants.REDIS_KEY_SHIELD_SMS);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS, phoneSet);
    }

    /**
     * 屏蔽短信-增加到列表(内部手动使用)
     *
     * @param phone
     *
     * @return
     */
    @RequestMapping("shield/add")
    @ResponseBody
    public ResponseVO<Void> addShieldPhone(String phone) {
        log.info("addShieldPhone phone:{}", phone);

        RedisUtils.sadd(RedisConstants.REDIS_KEY_SHIELD_SMS, phone);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    /**
     * 屏蔽短信-从列表移除(内部手动使用)
     *
     * @param phone
     *
     * @return
     */
    @RequestMapping("shield/remove")
    @ResponseBody
    public ResponseVO<Void> removeShieldPhone(String phone) {
        log.info("removeShieldPhone phone:{}", phone);

        RedisUtils.srem(RedisConstants.REDIS_KEY_SHIELD_SMS, phone);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    private boolean containsShieldPhone(String phone) {
        return RedisUtils.sismember(RedisConstants.REDIS_KEY_SHIELD_SMS, phone);
    }
}
